﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using smartBrowser.Util;
using smartBrowser.GUI;
using SemWeb;
using System.IO;
using System.Windows.Forms;

namespace smartBrowser.Task
{
    public class SwoogleTask : Task
    {
        private Hashtable ontologyList;

        public SwoogleTask(WebSite webSite, TabPageForm form, Hashtable ontologyList)
            : base(webSite, form)
        {
            this.ontologyList = ontologyList;
        }

        protected override void Execute()
        {
            try
            {
                if (this.ontologyList.Count == 0)
                {
                    foreach (Tag tag in webSite.TopKeywords)
                    {
                        String concept = tag.Concept;
                        concept = concept.Trim();
                        concept = concept.Replace(' ', '_');
                        List<Uri> uris = SwoogleSearchService.Query(concept);

                        for (int i = 0; i < uris.Count; i++)
                        {
                            MemoryStore store = this.load(uris[i]);
                            if (store != null && store.StatementCount > 0 && this.ontologyList.Count == 0)
                            {
                                Tag tag1 = null;

                                foreach (Entity entity in store.GetEntitiesOfType("http://www.w3.org/2000/01/rdf-schema#Class"))
                                {
                                    tag1 = Ontology.Ontology.parseUri(entity.Uri.ToLower());

                                    if (tag1.Concept.ToLower().Equals(concept.ToLower()))
                                    {
                                        MessageBox.Show("Concept: " + concept);                                                                                
                                        MessageBox.Show("entity uri: " + entity.Uri);  
                                        i = uris.Count;
                                        Console.Out.WriteLine("A ontologia sacada tem o conceito: " + concept);
                                        
                                        //Passa a keyword do website para o lado dos conceitos
                                        Tag tagAprendeu = (Tag)webSite.KeyWords[concept];
                                        webSite.KeyWords.Remove(concept);
                                        webSite.Concepts.Add(concept, tagAprendeu);                                        
                                        
                                        //Adiciona o conceito aprendido à ontologia local
                                        smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)("#"+tag1.Concept), (Entity)"http://www.w3.org/2000/01/rdf-schema#Type", (Entity)"http://www.w3.org/2000/01/rdf-schema#Class"));
                                        //smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)entity.Uri, (Entity)"http://www.w3.org/2000/01/rdf-schema#subClassOf", (Entity)"http://ontosem.org/#all"));
                                       
                                        expandToFathers(entity, store);

                                        smartBrowser.GUI.SmartBrowser.Instance.Ontologia.SaveOntology();
                                        
                                        Console.Out.WriteLine("Swoogle devolveu-me Uri: " + uris[0].AbsoluteUri);
                                        this.ontologyList.Add(concept, store);
                                        
                                        break;
                                    }
                                }

                            }
                        }
                    }
                }
            }catch(Exception){
            }

            FireCompleteEvent();
            Console.Out.WriteLine("Swoogle Task Complete");
        }

        private void expandToFathers(Entity actual, MemoryStore store)
        {
            try
            {
                MessageBox.Show("Actual: " + actual.Uri);
                Tag actualTag = Ontology.Ontology.parseUri(actual.Uri.ToLower());
                List<Entity> pais = new List<Entity>();
                //Ver as propriedades que este conceito tem
                SelectResult result = store.Select(new Statement(actual, null, null));
                MemoryStore resultStore = result.Load();
                foreach (Statement statement in resultStore)
                {                   

                    if (statement.Predicate.Uri.ToLower().Equals("http://www.w3.org/2000/01/rdf-schema#comment"))
                    {
                        MessageBox.Show("Encontrei comment");
                        smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)"#"+actualTag.Concept, (Entity)statement.Predicate, (Literal)statement.Object));
                    }
                    else if (statement.Predicate.Uri.ToLower().Equals("http://www.w3.org/2000/01/rdf-schema#subclassof"))
                    {
                        MessageBox.Show("Encontrei pai: " + statement.Object.Uri);
                        pais.Add((Entity)statement.Object);
                    }
                }

                if (pais.Count > 0)
                {
                    MessageBox.Show("Pais > 0");
                    foreach (Entity pai in pais)
                    {
                        Tag tag1 = Ontology.Ontology.parseUri(pai.Uri.ToLower());
                        if (smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Ontologia.ContainsKey(tag1.Concept.ToLower()))
                        {
                            MessageBox.Show("Contém a key");
                            Tag tagInLocalOntology = (Tag)smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Ontologia[tag1.Concept.ToLower()];
                            smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)("#"+actualTag.Concept), (Entity)"http://www.w3.org/2000/01/rdf-schema#subClassOf", (Entity)("#"+tag1.Concept)));
                        }
                        else
                        {
                            MessageBox.Show("Não contém a key, vou continuar a subir");
                            smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)("#"+tag1.Concept), (Entity)"http://www.w3.org/2000/01/rdf-schema#Type", (Entity)"http://www.w3.org/2000/01/rdf-schema#Class"));
                            smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)("#"+actualTag.Concept), (Entity)"http://www.w3.org/2000/01/rdf-schema#subClassOf", (Entity)("#"+tag1.Concept)));
                            expandToFathers(pai, store);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Pais < 0, vou adicionar à raiz da ontologia local");
                    smartBrowser.GUI.SmartBrowser.Instance.Ontologia.Store.Add(new Statement((Entity)("#"+actualTag.Concept), (Entity)"http://www.w3.org/2000/01/rdf-schema#subClassOf", (Entity)"#Entity"));
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show("Exception: " + exp);
            }
        }

        private MemoryStore load(Uri uri)
        {                        
            MemoryStore store = new MemoryStore();            
            String name = uri.AbsoluteUri;

            //Carrega o rdf do uri           
            try
            {                
                RdfReader rdf = RdfXmlReader.LoadFromUri(uri);              
                store.Import(rdf);                                
                rdf.Dispose();
                Console.Out.WriteLine("Ontology Loaded from URI: "+uri.AbsoluteUri);
                return store;

            }
            catch (Exception exc)
            {
               Console.Out.WriteLine("Error loading the ontology from swoogle ["+uri.AbsoluteUri+"] : "+exc.Message);
            }

            return null;
        }

        public MemoryStore getFile(Uri uri)
        {
            Boolean got = false;
            
            try
            {
                System.Net.WebClient client = new System.Net.WebClient();
                client.DownloadFile(uri.AbsoluteUri, "temp.owl");
                got = true;
            }
            catch (Exception exc)
            {
                Console.Out.WriteLine("Error saving ontology: "+exc.Message);
            }

            if (got)
            {
                try
                {
                    RdfXmlReader rdf = new RdfXmlReader("temp.owl");
                    MemoryStore store = new MemoryStore();
                    store.Import(rdf);
                    rdf.Dispose();
                    Console.Out.WriteLine("Ontology Loaded sucessfully.");
                    return store;
                }
                catch (Exception exc)
                {
                    Console.Out.WriteLine("Error loading ontology from swoogle: " + exc.Message);
                }
            }

            return null;
        }

        public Hashtable OntologyList
        {
            get
            {
                return this.ontologyList;
            }
        }
    }
}
